#include <stdio.h>              // standard C libraries
#include <stdlib.h>
#include <cstring>
#include <math.h>
#include <time.h>
#include <vector>
#include <omp.h>
#include <iostream>

using namespace std;

typedef struct pt
{
   int x, y;
}MyPoint;

#define pi 3.14159265

#define edge_pixels 5000

MyPoint edgePixels[edge_pixels];


void houghTransform();
void createImage();


int main(int argc, char **argv)
{
	double start_time = 0.0, end_time = 0.0, execution_time = 0.0;
	
	createImage();
	
	start_time = omp_get_wtime();
	houghTransform();
	end_time = omp_get_wtime();
	
	printf("execution time: %f\n", end_time - start_time);

	return 0;
}

void createImage()
{
	int x, y, i;
	for(i =0, x = 200, y = 200; x < edge_pixels+200; x++, y++, i++)
	{
		MyPoint temp_pt;
				
		temp_pt.x = x;
		temp_pt.y = y;
		edgePixels[i] = temp_pt;
	}	
}
void initializeMatrix(int **matrix, int numRows, int numCols) {
	for(int i = 0; i < numRows; i++)
		matrix[i] = new int[numCols];

	for(int i = 0; i < numRows; i++)
		for(int j = 0; j < numCols; j++)
			matrix[i][j] = 0;
}

void houghTransform()
{
	int **accumulator;
	accumulator = new int*[360];
	
	initializeMatrix(accumulator, 360,edge_pixels*2);
	
	float rho, theta;
	
	printf("hough\n");

	int highest = 0;
	omp_set_num_threads(8);
	
	omp_lock_t lock;

	omp_init_lock(&lock);
	#pragma omp parallel for
	for (int i = 0; i < edge_pixels; i++)
	{
		for (int index = 0; index < 360; index++)
		{
			omp_set_lock(&lock);
			//printf("i: %d, index: %d\n", i, index);
			accumulator[index][(int)(fabs(((float)edgePixels[i].x * cos((float)index*(pi/180.0))) + ((float)edgePixels[i].y * sin((float)index*(pi/180.0)))))+1]++;
			omp_unset_lock(&lock);
		}
	}		
}

